#include "OpenglWidget.h"

OpenglWidget::OpenglWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    QImageReader::setAllocationLimit(1024);
    setCursor(Qt::OpenHandCursor);
}

OpenglWidget::~OpenglWidget()
{
    makeCurrent();
    vao.destroy();
    vbo.destroy();
    texture.destroy();
    doneCurrent();
}

void OpenglWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);

    shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertexShaderSource.vert");
    shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragmentShaderSource.frag");
    shader.link();
    vao.create();
    vao.bind();
    vbo.create();
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices.data(), vertices.size() * sizeof(float));
    shader.setAttributeArray("aPos", GL_FLOAT, 0, 3, 3 * sizeof(float));
    shader.enableAttributeArray("aPos");
    // QImage image(QSize(100, 100), QImage::Format_ARGB32);
    // image.fill(QColor(75, 116, 150));
    // setImage(image);
}
void OpenglWidget::setImage(QImage &image)
{
    if (texture.isCreated())
        texture.destroy();
    texture.create();
    texture.bind();
    texture.setData(image);
    texture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
    texture.setWrapMode(QOpenGLTexture::ClampToEdge);
    update();
    if (image.width() * 1.0 / image.height() == 2.0)
        emit loadImagFilsh();
}
void OpenglWidget::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);

    texture.bind();
    shader.bind();

    projection.setToIdentity();
    view.setToIdentity();
    model.setToIdentity();
    projection.perspective(fov, (float)width() / height(), 0.1f, 10.0f);
    view.lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
    shader.setUniformValue("projection", projection);
    shader.setUniformValue("view", view);
    shader.setUniformValue("model", model);
    // 绘制立方体
    vao.bind();
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());

    vao.release();
    shader.release();
    texture.release();
}

void OpenglWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}
void OpenglWidget::mouseMoveEvent(QMouseEvent *event)
{

    if (!isLeftButtonPressed)
        return;
    // 计算鼠标位移
    QPoint delta = event->pos() - lastMousePos;
    lastMousePos = event->pos();

    float mouseSensitivity = sets.value("mouseSensitivity", 15).toFloat() / 10000;

    // 更新欧拉角
    yaw -= delta.x() * mouseSensitivity * fov;
    pitch += delta.y() * mouseSensitivity * fov; // 注意方向相反

    // 限制俯仰角范围，防止视角翻转
    if (pitch > 89.0f)
        pitch = 89.0f;
    if (pitch < -89.0f)
        pitch = -89.0f;

    // 根据欧拉角更新相机朝向

    cameraFront.setX(qCos(qDegreesToRadians(yaw)) * cos(qDegreesToRadians(pitch)));
    cameraFront.setY(qSin(qDegreesToRadians(pitch)));
    cameraFront.setZ(qSin(qDegreesToRadians(yaw)) * cos(qDegreesToRadians(pitch)));
    cameraFront = cameraFront.normalized();

    update(); // 请求重绘
}
void OpenglWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isLeftButtonPressed = true;
        lastMousePos = event->pos();
        setCursor(Qt::ClosedHandCursor);
    }
}
void OpenglWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isLeftButtonPressed = false;
        setCursor(Qt::OpenHandCursor);
    }
}
void OpenglWidget::wheelEvent(QWheelEvent *event)
{
    // 获取滚轮滚动量
    int delta = event->angleDelta().y();

    float mouseFov = sets.value("mouseFov", 80).toFloat() / 20;

    // 更新视场角
    fov -= (float)delta / 120.0f * mouseFov;

    // 限制视场角范围
    if (fov < 5.0f)
        fov = 5.0f;
    if (fov > 160.0f)
        fov = 160.0f;

    update(); // 请求重绘
}
